//
//  HealthTool.swift
//  MySport
//
//  Created by lanou3g on 16/2/27.
//  Copyright © 2016年 ccsobj. All rights reserved.
//

import UIKit

import HealthKit

import Async


struct CharacteristicType  {
   static let  dateOfBirth = HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth)!
   static let bloodType = HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBloodType)!
   static let sex =  HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex)!
    //            数据采样信息（身体质量、身高）
   static let weight = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)!
   static let height = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)!
    //            锻炼与健身的信息
  static  let workoutType = HKObjectType.workoutType()
    
  static  let BMI = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex)!
  static let energyBurned = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)!
   static let walkingRunning =  HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)!
}

private let healthStrore = HKHealthStore()
//private let healthTool = HKHealthManage()
private let _healthTool = HealthTool()



class HealthTool: NSObject {
    
    typealias DoubleResultClosure = (Double?)->Void
    typealias HealthInfoResultClosure = (HealthInfo)->Void
    
    class func shareHealthTool()->HealthTool{
        return _healthTool
    }
    
    
    static private var isAuthorized : Bool = false
    
    private override init() {}
    
    static var available : Bool{
        return HKHealthStore.isHealthDataAvailable()
    }
    private static let healthkitTypeToRead : NSSet = NSSet(array:[
            CharacteristicType.dateOfBirth,CharacteristicType.height,CharacteristicType.weight,CharacteristicType.bloodType,CharacteristicType.BMI,CharacteristicType.sex,CharacteristicType.energyBurned,CharacteristicType.workoutType,CharacteristicType.walkingRunning])
    private static let healthkitTypeToWrite : NSSet = NSSet(array:[
        CharacteristicType.dateOfBirth,CharacteristicType.height,CharacteristicType.weight,CharacteristicType.bloodType,CharacteristicType.BMI,CharacteristicType.sex,CharacteristicType.energyBurned,CharacteristicType.workoutType,CharacteristicType.walkingRunning
        ])
    
//    获取Health的授权
    class func authorizeHealthKit(completion:((isSuccess:Bool,error:NSError!)->Void)!){
        healthStrore.requestAuthorizationToShareTypes(healthkitTypeToWrite as? Set<HKSampleType>, readTypes:healthkitTypeToRead as? Set<HKObjectType>){
            completion(isSuccess: $0,error: $1)
            if $0{
                isAuthorized = true
            }else{
                print($1)
            }
        }
    }
    
//    从Health获取数据
    class func getInfoFromHealth(complete:HealthInfoResultClosure){
        if !isAuthorized{
            authorizeHealthKit(){_,_ in}
        }
        let healthInfo = HealthInfo()
        healthInfo.sex = try? healthStrore.biologicalSex().biologicalSex
        healthInfo.birthDay = try? healthStrore.dateOfBirth()
        healthInfo.bloodType = try? healthStrore.bloodType().bloodType
        getHeight(){result in
            healthInfo.height = result
            getWeight(){result in
                healthInfo.weight = result
                complete(healthInfo)
                }
            }
        }
}

extension HealthTool{
    private class func getHeight(complete:DoubleResultClosure){
        let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)
        readMostRecentSample(sampleType!) {sample,err in
            if let height = (sample as? HKQuantitySample)?.quantity.doubleValueForUnit(HKUnit.meterUnit()){
                complete(height)
            }else{
                complete(nil)
            }
        }
    }
    
    private class func getWeight(complete:DoubleResultClosure){
        let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)
        readMostRecentSample(sampleType!) {sample,err in
            if let result = (sample as? HKQuantitySample)?.quantity.doubleValueForUnit(HKUnit.gramUnit()){
                let weight = result / 1000.0
                complete(weight)
            }else{
                complete(nil)
            }
        }
    }
    
    private class func readMostRecentSample(sampleType:HKSampleType,complete:(HKSample?,NSError!)->Void){
        let past = NSDate.distantPast()
        let now = NSDate()
        let mostRecentPredicate = HKQuery.predicateForSamplesWithStartDate(past, endDate:now,options: .None)
        let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierStartDate, ascending:true)
        
        let sampleQuery = HKSampleQuery(sampleType:sampleType, predicate: mostRecentPredicate, limit:1, sortDescriptors:[sortDescriptor]){_,samples,err in
            if err != nil {
                complete(nil,err)
                return
            }
            let mostRecentSample = samples?.first as? HKQuantitySample
            complete(mostRecentSample,err)
        }
        healthStrore.executeQuery(sampleQuery)
    }
}


